package com.dstz.form.generator;

import org.jsoup.nodes.Element;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dstz.base.api.exception.BusinessException;
import com.dstz.base.core.util.AppUtil;
import com.dstz.base.core.util.StringUtil;
import com.dstz.base.core.util.ThreadMapUtil;
import com.dstz.bus.api.constant.BusTableRelType;
import com.dstz.bus.api.model.IBusTableRel;
import com.dstz.bus.api.model.IBusinessColumn;
import com.dstz.form.model.design.FormColumn;
import com.dstz.form.model.design.FormGroup;

import cn.hutool.core.collection.CollectionUtil;
/**
 * iview 表单生成器
 * @author jeff
 *
 */
//@Component
public class IviewFormElementGenerator extends AbsFormElementGenerator{

	@Override
	public String getGeneratorName() {
		return "iviewGenerator";
	}

	private void handleVModel(Element element, IBusinessColumn column) {
		String boCode = (String) ThreadMapUtil.get("boCode");
		IBusTableRel relation = (IBusTableRel) ThreadMapUtil.get("relation");
		// 如果是多行子表
		if (relation.getType().equals(BusTableRelType.ONE_TO_MANY.getKey())) {
			element.attr("v-model", column.getTable().getKey() + "." + column.getKey());
			return;
		}

		element.attr("v-model", getScopePath(relation) + "." + column.getKey());
		
		handleElementPlaceHolder(column, element);
	}

	@Override
	protected String getColumnOnetext(IBusinessColumn column) {

		Element element = getElement("i-input");

		handleVModel(element, column);
		handlePermission(element, column);
		handleValidateRules(element, column);

		return element.toString();
	}

	/**
	 * <ab-date class=" form-control" v-model="data.bdkj.rqkj" desc="日期控件" ab-validate="{}" v-ab-permission="permission.bdkj.bdkj.rqkj" format="yyyy-MM-dd"></ab-date>
	 */
	@Override
	protected String getColumnDate(IBusinessColumn column) {
		Element element = getElement("ab-date");//.attr("style", "width: 200px");

		handleVModel(element, column);
		element.attr("v-bind:ab-permission", getPermissionPath(column));
		element.attr("desc",column.getTable().getComment()+"-"+column.getComment());
		// TODO 不支持校验handleValidateRules(element, column);

		String configStr = column.getCtrl().getConfig();
		if (StringUtil.isEmpty(configStr)) {
			throw new BusinessException(String.format("表【%s】日期字段  【%s】解析失败,配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		String format = JSON.parseObject(configStr).getString("format");
		// yyyy-MM-dd HH:mm:ss pc 移动端为：YYYY-MM-DD HH:mm
		element.attr("format", format);
		
		return element.toString();
	}

	@Override
	protected String getColumnDic(IBusinessColumn column) {
		Element element = getElement("ab-dict");//.attr("style", "width: 200px");

		handleVModel(element, column);
		element.attr("v-bind:ab-permission", getPermissionPath(column));
		element.attr("desc",column.getTable().getComment()+"-"+column.getComment());
		//TODO 暂不支持校验

		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("key")) {
			throw new BusinessException(String.format("表【%s】数据字典  字段【%s】解析失败,alias 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		element.attr("dict-key", config.getString("key"));
		
		return element.toString();
	}

	/**
	 * <pre>
	 * ab-serial-no
	 * </pre>
	 */
	@Override
	protected String getColumnIdentity(IBusinessColumn column) {
		Element element = getElement("ab-serial-no");//.attr("style", "width: 200px");
		handleVModel(element, column);
		element.attr("v-bind:ab-permission", getPermissionPath(column));
		handleValidateRules(element, column);

		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("alias")) {
			throw new BusinessException(String.format("表【%s】流水号  字段【%s】解析失败,alias 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}
		element.attr("serial-no", config.getString("alias"));
		
		return element.toString();
	}

	@Override
	protected String getColumnMultitext(IBusinessColumn column) {
		//TODO 支持宽高设置
		Element element = getElement("i-input").attr("type", "textarea");//.attr("style", "width: 200px");

		handleVModel(element, column);
		handlePermission(element, column);
		handleValidateRules(element, column);

		return element.toString();
	}

	/**
	 * <pre>
	 * <ab-checkbox-group v-model="data.kjcs.fxk">
	 * 			<checkbox label="1">A</checkbox>
	 * 			<checkbox label="2">B</checkbox>
	 * 		</ab-checkbox-group>
	 * </pre>
	 */
	@Override
	protected String getColumnCheckBox(IBusinessColumn column) {
		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("options")) {
			throw new BusinessException(String.format("表【%s】CheckBox 字段  【%s】解析失败,options 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		Element checkbox = getElement("ab-checkbox-group");
		handleVModel(checkbox, column);
		handlePermission(checkbox, column);
		handleValidateRules(checkbox, column);

		JSONArray options = config.getJSONArray("options");
		for (int i = 0; i < options.size(); i++) {
			JSONObject option = options.getJSONObject(i);

			Element checkboxEl = checkbox.appendElement("checkbox");
			checkboxEl.attr("label",option.getString("key"));
			checkboxEl.appendText(option.getString("txt"));
		}
		return checkbox.toString();
	}

	@Override
	protected String getColumnRadio(IBusinessColumn column) {
		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("options")) {
			throw new BusinessException(String.format("表【%s】Radio 字段  【%s】解析失败,options 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		Element radioGroup = getElement("radio-group");
		JSONArray options = config.getJSONArray("options");

		handleVModel(radioGroup, column);
		handlePermission(radioGroup, column);
		handleValidateRules(radioGroup, column);

		for (int i = 0; i < options.size(); i++) {
			JSONObject option = options.getJSONObject(i);

			Element label = radioGroup.appendElement("radio");
			label.attr("label",option.getString("key"));
			label.appendText(option.getString("txt"));
		}

		return radioGroup.toString();
	}

	@Override
	protected String getColumnSelect(IBusinessColumn column, Boolean isMultiple) {
		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("options")) {
			throw new BusinessException(String.format("表【%s】Select 字段  【%s】解析失败,options 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		Element iSelectEl = getElement("i-select");//.attr("style", "width: 200px");
		handleVModel(iSelectEl, column);
		handlePermission(iSelectEl, column);
		handleValidateRules(iSelectEl, column);
		iSelectEl.attr(":disabled","'r'=="+getPermissionPath(column));

		if (isMultiple) {
			iSelectEl.attr("multiple", "true");
		}

		Element select = iSelectEl.appendElement("i-option");
		select.attr("value", "");
		select.text("请选择");

		JSONArray options = config.getJSONArray("options");
		for (int i = 0; i < options.size(); i++) {
			JSONObject option = options.getJSONObject(i);

			Element element = iSelectEl.appendElement("i-option");
			element.attr("value", option.getString("key"));
			element.text(option.getString("txt"));
		}

		return iSelectEl.toString();
	}
	
	//<ab-upload v-model="data.kjcs.fjsc">​</ab-upload>
	protected String getColumnFile(IBusinessColumn column) {
		Element element = getElement("ab-upload");
		handleVModel(element, column);
		element.attr("v-bind:ab-permission", getPermissionPath(column));
		element.attr("desc",column.getTable().getComment()+"-"+column.getComment());
		//TODO 暂不支持校验Validate
		return element.toString();
	}


	/**
	 * 获取三层子表的必须属性
	 * v-model="subTempData.SchoolStudent_Student_Model"
	 * 	@on-ok="subTempData.SchoolStudent_Student_okFn()"
	 * 	@on-cancel="subTempData.SchoolStudent_Student_Model=false"
	 * 	table-key="Student" ab-show-permission="tablePermission.SchoolStudent.Student"
	 */
	@Override
	public String getSubAttrs(IBusTableRel rel) {
		if(rel.getType().equals(BusTableRelType.MAIN.getKey()))return "";
		StringBuilder sb = new StringBuilder();
		sb.append(" table-key=\"" + rel.getTableKey() + "\" ");
		// 一对多的三层情况下弹框展示
		if (rel.getType().equals(BusTableRelType.ONE_TO_MANY.getKey()) && !rel.getParent().getType().equals(BusTableRelType.MAIN.getKey())) {
			sb.append(" v-model=" + "\"subTempData." + rel.getBusObj().getKey() + "_" + rel.getTableKey() + "_Model\" ");
			sb.append(" @on-ok=" + "\"subTempData." + rel.getBusObj().getKey() + "_" + rel.getTableKey() + "_okFn()\" ");
			sb.append(" @on-cancel=" + "\"subTempData." + rel.getBusObj().getKey() + "_" + rel.getTableKey() + "_Model=false\" ");
		}
		return sb.toString();
	}
	
	public String getGroupTableName(FormGroup group) {
		if(CollectionUtil.isEmpty(group.getColumnList()))return "";
		String tableKey = null;
		
		for(FormColumn column : group.getColumnList()) {
			if(tableKey != null && !tableKey.equals(column.getTableKey())) {
				return "";
			}
			tableKey = column.getTableKey();
		}
		if(group.getTableRelation().getTableKey().equals(tableKey)) {
			return "";
		}
			
		return " table-key=\"" + tableKey + "\" "; 
		
	}
	
	public Boolean isMultilayer(IBusTableRel rel) {
		if (rel.getType().equals(BusTableRelType.ONE_TO_MANY.getKey()) && !rel.getParent().getType().equals(BusTableRelType.MAIN.getKey())) {
			return true;
		}
		return false;
	}

	@Override
	protected void handlePermission(Element element, IBusinessColumn column) {
		element.attr("v-ab-permission", getPermissionPath(column));
	}

	@Override
	protected void handleValidateRules(Element element, IBusinessColumn column) {
		super.handleValidateRules(element, column);
		element.attr("v-ab-validate", element.attr("ab-validate"));
		element.attr("desc",column.getTable().getComment()+"-"+column.getComment());
		element.removeAttr("ab-validate");
	}
	
	@Override
	public String getScopePath(IBusTableRel relation) {
		return AppUtil.getBean(VueFormElementGenerator.class).getScopePath(relation);
	}
	
	public String getScopePath_old(IBusTableRel relation) {
		return super.getScopePath(relation);
	}
	
	/**
	 * 权限路径
	 * @param column
	 * @return
	 */
	@Override
	protected String getPermissionPath(IBusinessColumn column) {
		return AppUtil.getBean(VueFormElementGenerator.class).getPermissionPath(column);
	}
	
	/**
	 * <pre>
	 * 行内专用
	 * </pre>	
	 * @param column
	 * @param relation
	 * @return
	 */
	public String getLineColumn(IBusinessColumn column,IBusTableRel relation) {
		ThreadMapUtil.put("isLine", true);
		String str = super.getColumn(column, relation);
		ThreadMapUtil.remove("isLine");
		return str;
	}
	
	public String getLineColumn(FormGroup group,FormColumn formColumn) {
		IBusTableRel tableRel = group.getTableRelation();
		
		// 一对一子表 的TableRelation 需要从父表中获取
		if(StringUtil.isNotEmpty(formColumn.getTableKey())&& !formColumn.getTableKey().equals(tableRel.getTableKey())) {
			IBusTableRel table = tableRel.find(formColumn.getTableKey());
			if(table != null) {
				tableRel = table;
			}
		}
		
		if(!formColumn.getTableKey().equals(tableRel.getTableKey())) {
			LOG.error("生成表单可能存在异常！formColumnTableKey{},tableRelTableKey{}",formColumn.getTableKey(),tableRel.getTableKey());
		}
		
	    IBusinessColumn businessColumn = tableRel.getTable().getColumnByKey(formColumn.getKey());
		
	    if(businessColumn == null) {
	    	LOG.error("布局模板查找Column配置失败！字段：{}，表：{}",formColumn.getComment(),formColumn.getTableKey());
	    }
	    
		return this.getLineColumn(businessColumn, tableRel);
	}
}